
<!DOCTYPE html>
<html lang="en">
    <head><meta name="generator" content="Hexo 3.9.0">
    
        <title>FairyGUI - 事件机制</title>
    
        <meta charset="utf-8">
        <meta name="description" content="FairyGUI教程">
        <meta name="keywords" content="FairyGUI,FGUI,FairyGUI教程">
        
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

        <meta property="og:type" content="article">
        <meta property="og:title" content="-事件机制FairyGUI">
        <meta property="og:description" content="FairyGUI教程">

        <meta name="twitter:card" content="summary">
        <meta name="twitter:title" content="事件机制 — FairyGUI">
        <meta name="twitter:description" content="FairyGUI教程">

      <!--  <link href='//fonts.proxy.ustclug.org/css?family=Source+Sans+Pro:300,400,600|Roboto Mono' rel='stylesheet' type='text/css'> -->

        <!-- main page styles -->
        <link rel="stylesheet" href="/docs/css/page.css">

        <!-- this needs to be loaded before guide's inline scripts -->
        <script src="/docs/js/vue.min.js"></script>
        <script>window.PAGE_TYPE = "guide_unity"</script>
    </head>
    <body class="docs">        <div id="mobile-bar" data-bg-text="FairyGUI">
            <a class="menu-button"></a>
        </div>
        <div id="header">
  <ul id="nav">
    <li><a href="/docs/guide/" class="nav-link current">教程</a></li>
<li><a href="/docs/examples/" class="nav-link">在线示例</a></li>
<li><a href="/docs/release_notes/" class="nav-link">发行日志</a></li>
<li><a href="/" class="nav-link">首页</a></li>
  </ul>
</div>

        
            <div id="main" class="fix-sidebar">
                
                    
    <div class="sidebar">
    <ul class="main-menu">
        <li><a href="/docs/guide/" class="nav-link current">教程</a></li>
<li><a href="/docs/examples/" class="nav-link">在线示例</a></li>
<li><a href="/docs/release_notes/" class="nav-link">发行日志</a></li>
<li><a href="/" class="nav-link">首页</a></li>
    </ul>
    <div class="list">
        <ul class="menu-root">
            

	 			
	                
	                <li>
	                    <a href="/docs/guide/index.html" class="sidebar-link">导读</a>
	                </li>
	            
	
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/index.html" class="sidebar-link">编辑器使用基础</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/project_settings.html" class="sidebar-link">项目设置</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/package.html" class="sidebar-link">包</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/branch.html" class="sidebar-link">分支</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/publish.html" class="sidebar-link">发布</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/object.html" class="sidebar-link">元件</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/image.html" class="sidebar-link">图片</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/movieclip.html" class="sidebar-link">动画</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/graph.html" class="sidebar-link">图形</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/loader.html" class="sidebar-link">装载器</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/text.html" class="sidebar-link">文本</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/richtext.html" class="sidebar-link">富文本</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/group.html" class="sidebar-link">组</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/component.html" class="sidebar-link">组件</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/scrollpane.html" class="sidebar-link">滚动容器</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/controller.html" class="sidebar-link">控制器</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/relation.html" class="sidebar-link">关联系统</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/label.html" class="sidebar-link">标签</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/button.html" class="sidebar-link">按钮</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/combobox.html" class="sidebar-link">下拉框</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/progressbar.html" class="sidebar-link">进度条</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/slider.html" class="sidebar-link">滑动条</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/scrollbar.html" class="sidebar-link">滚动条</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/list.html" class="sidebar-link">列表</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/tree.html" class="sidebar-link">树</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/popup.html" class="sidebar-link">Popup</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/dragdrop.html" class="sidebar-link">Drag&Drop</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/window.html" class="sidebar-link">窗口系统</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/transition.html" class="sidebar-link">动效</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/adaptation.html" class="sidebar-link">适配</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/i18n.html" class="sidebar-link">多国语言</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/export.html" class="sidebar-link">导入和导出</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/preference.html" class="sidebar-link">偏好设置</a>
	                </li>
	            
	                
	                <li>
	                    <a href="/docs/guide/editor/plugin.html" class="sidebar-link">插件</a>
	                </li>
	            
	
	            
	                
	                
	                <li><h3>SDK</h3></li>
	                
	                <li>
	                    <a href="/docs/guide/sdk/laya.html" class="sidebar-link">LayaAir</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/sdk/egret.html" class="sidebar-link">Egret</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/sdk/cocos2dx.html" class="sidebar-link">Cocos2dx</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/sdk/creator.html" class="sidebar-link">Cocos Creator</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/sdk/cryengine.html" class="sidebar-link">Cry Engine</a>
	                </li>
	            

	            
	                
	                
	                <li><h3>SDK - Unity</h3></li>
	                
	                <li>
	                    <a href="/docs/guide/unity/index.html" class="sidebar-link">显示UI面板</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/transform.html" class="sidebar-link">坐标系统</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/atlas.html" class="sidebar-link">纹理集的处理</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/font.html" class="sidebar-link">字体的处理</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/input.html" class="sidebar-link">输入处理</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/event.html" class="sidebar-link current">事件机制</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/insert3d.html" class="sidebar-link">插入模型/粒子/Spine/Canvas</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/uipainter.html" class="sidebar-link">曲面UI</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/drawcall.html" class="sidebar-link">DrawCall优化</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/lua.html" class="sidebar-link">在Lua中使用</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/special.html" class="sidebar-link">特色功能</a>
	                </li>
	            
	                
	                
	                <li>
	                    <a href="/docs/guide/unity/faq.html" class="sidebar-link">常见问题</a>
	                </li>
	            

            
        </ul>
    </div>
</div>


<div class="content guide_unity with-sidebar ">
    
      <h1>事件机制</h1>
    
    <p><code>EventDispatcher</code>是事件分发的中心，GObject就是一个EventDispatcher。每个事件类型都对应一个<code>EventListener</code>，接收事件并调用处理函数。</p>
<p>例如，编写某个元件单击的处理逻辑：</p>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">aObject.onClick.Add(aCallback);</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">aCallback</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">//some logic</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="冒泡和捕获"><a href="#冒泡和捕获" class="headerlink" title="冒泡和捕获"></a>冒泡和捕获</h2><p>一些特殊的事件，比如鼠标/触摸事件，具备向父组件传递的特性，这个传递过程叫做冒泡。例如当手指接触A元件时，A元件触发TouchBegin事件，然后A元件的父组件B触发TouchBegin事件，然后B的父组件C也触发TouchBegin事件，以此类推，直到舞台根部。这个设计保证了所有相关的显示对象都有机会处理触摸事件，而不只是最顶端的显示对象。</p>
<p>冒泡过程可以被打断，通过调用EventContext.StopPropagation()可以使冒泡停止向父组件推进。</p>
<p>从上面的冒泡过程可以看出，事件处理的顺序应该是：A’s listeners-&gt;B’s listeners-&gt;C’s listeners，这里还有一种机制可以让链路上任意一个对象可以提前处理事件，这就是事件捕获。事件捕获是反向的，例如在上面的例子中，就是C先捕获事件，然后是B，再到A。所以所有事件处理的完整顺序应该是：</p>
<p>C’s capture listeners-&gt;B’s capture listeners-&gt;A’s capture listeners-&gt;A’s listeners-&gt;B’s listeners-&gt;C’s listeners</p>
<p>捕获传递链是不能中止的，冒泡传递链可以通过StopPropagation中止。<br>事件捕获的设计可以使父元件优于子元件和孙子元件检查事件。</p>
<p>并非所有事件都有冒泡设计，在非冒泡事件中，capture的回调优于普通回调，仅此而已，可以作为一个优先级特性来使用。</p>
<h2 id="事件回调函数"><a href="#事件回调函数" class="headerlink" title="事件回调函数"></a>事件回调函数</h2><p>每个事件可以注册一个或多个回调函数。函数原型为：</p>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">delegate</span> <span class="keyword">void</span> <span class="title">EventCallback0</span>(<span class="params"></span>)</span>;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">delegate</span> <span class="keyword">void</span> <span class="title">EventCallback1</span>(<span class="params">EventContext context</span>)</span>;</span><br></pre></td></tr></table></figure>
<p>两种形式的使用方法都是相同的，差别在于不带参数或带一个参数,只是为了方便在不需要用到EventContext时少写一点而已。</p>
<p>没有直接传递自定义参数进回调函数的办法。但可以通过三种方式间接实现：</p>
<ol>
<li>通过全局或者模块变量；</li>
<li><p>使用lamba表达式，例如：</p>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">a.onClick.Add(()=&gt;&#123; ... &#125;);</span><br></pre></td></tr></table></figure>
</li>
<li><p>将变量放到显示对象的data属性里。例如:</p>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">a.data = ...;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">aCallback</span>(<span class="params">EventContext context</span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    Debug.Log(((GObject)context.sender).data)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h2 id="EventListener"><a href="#EventListener" class="headerlink" title="EventListener"></a>EventListener</h2><ul>
<li><code>Add</code> <code>Remove</code> 添加或删除一个回调。</li>
<li><code>AddCapture</code> <code>RemoveCapture</code> 添加或删除一个捕获期回调。</li>
</ul>
<h2 id="EventContext"><a href="#EventContext" class="headerlink" title="EventContext"></a>EventContext</h2><p>EventContext是回调函数的参数类型。</p>
<ul>
<li><p><code>sender</code> 获得事件的分发者。</p>
</li>
<li><p><code>initiator</code> 获得事件的发起者。一般来说，事件的分发者和发起者是相同的，但如果事件已发生冒泡，则可能不相同。参考下面冒泡的描述。</p>
</li>
<li><p><code>type</code> 事件类型。</p>
</li>
<li><p><code>inputEvent</code> 如果事件是键盘/触摸/鼠标事件，通过访问inputEvent对象可以获得这类事件的相关数据。</p>
</li>
<li><p><code>data</code> 事件的数据。根据事件不同，可以有不同的含义。</p>
</li>
<li><p><code>StopPropagation</code> 点击子节点的区域，父节点也能收到触摸事件，这就是事件冒泡的特性。如果你不想再向父节点传递，可以调用这个方法。</p>
</li>
<li><p><code>CaptureTouch</code> 当鼠标左键释放或者手指抬起时，如果鼠标或者触摸位置已经不在组件范围内了，那么组件的TouchEnd事件是不会触发的。如果确实需要，可以请求捕获。在TouchBegin事件处理函数内，你可以调用context.CaptureTouch()，这样，无论鼠标在哪里释放（即使不在对象区域内），对象的onTouchEnd都会被调用。注意仅生效一次。<br>在1.9.1SDK后，如果调用了CaptureTouch，那么GObject.onTouchMove事件将在手指（或鼠标左键）抬起前一直触发（无论手指或指针位置是不是在该对象上方），直到鼠标左键释放或者手指抬起。</p>
</li>
<li><p><code>UncaptureTouch</code> 取消CaptureTouch发起的触摸事件捕获。</p>
</li>
</ul>
<h2 id="InputEvent"><a href="#InputEvent" class="headerlink" title="InputEvent"></a>InputEvent</h2><p>对键盘事件和鼠标/触摸事件，可以通过EventContext.inputEvent获得此类事件的相关数据。</p>
<ul>
<li><p><code>x</code> <code>y</code> 鼠标或手指的位置；这是舞台坐标，因为UI可能因为自适配发生了缩放，所以如果要转成UI元件中的坐标，要使用GObject.GlobalToLocal转换。</p>
</li>
<li><p><code>keyCode</code> 按键代码；</p>
</li>
<li><p><code>modifiers</code> 参考UnityEngine.EventModifiers。</p>
</li>
<li><p><code>mouseWheelDelta</code> 鼠标滚轮滚动值。</p>
</li>
<li><p><code>touchId</code> 当前事件相关的手指ID；在PC平台，该值为0，没有意义。</p>
</li>
<li><p><code>isDoubleClick</code> 是否双击。</p>
</li>
</ul>

    
    <div class="footer">
      发现错误或想贡献文档?
      <a href="https://github.com/fairygui/fairygui.github.io/tree/master/src/guide/unity/event.md" target="_blank">
        在 Github 上编辑此文档!
      </a>
    </div>
</div>

                
            </div>
            <script src="/docs/js/smooth-scroll.min.js"></script>
        

        <!-- main custom script for sidebars, version selects etc. -->        
        <script src="/docs/js/css.escape.js"></script>
        <script src="/docs/js/common.js"></script>
    </body>
</html>
